﻿namespace LP
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.CompilerServices;

    public sealed class WindowMgr : AbsMgr
    {
        private Dictionary<Type, AbsWindow> cacheWindows = new Dictionary<Type, AbsWindow>();
        private List<AbsWindow> windows = new List<AbsWindow>();
        private List<AbsWindow> residentWindows = new List<AbsWindow>();
        private UIMgr UIMgr;

        public override void OnInit()
        {
            base.OnInit();
            UIMgr = GLModuleMgr.Ins.RetriveModule<GlobleModule>().RetrieveMgr<UIMgr>();
        }

        public override void OnDestroy()
        {
            cacheWindows.Clear();
            foreach (var item in windows)
            {
                item.OnDestroy();
            }
            foreach (var item in residentWindows)
            {
                item.OnDestroy();
            }
            windows.Clear();
            residentWindows.Clear();
            base.OnDestroy();
        }

        public void ShowWindow<T>(ITuple tupel = null, Action action = null) where T : AbsWindow
        {
            try
            {
                Type type = typeof(T);
                if (!cacheWindows.TryGetValue(type, out var window))
                {
                    window = Activator.CreateInstance(type, UIMgr) as T;
                    cacheWindows.Add(type, window);
                    window.OnInit();
                }
                if (!windows.Contains(window))
                {
                    windows.Add(window);
                    window.OnShow(tupel, action);
                }
            }
            catch (System.Exception e)
            {
                UnityEngine.Debug.LogError(e.ToString());
            }
        }

        public void HideWindow<T>(ITuple tupe = null) where T : AbsWindow
        {
            Type type = typeof(T);
            if (cacheWindows.TryGetValue(type, out var window))
            {
                if (windows.Contains(window))
                {
                    window.OnHide(tupe);
                    windows.Remove(window);
                    RemoveCacheWindow(window);
                }
            }
        }

        /// <summary>
        /// 从最顶层开始隐藏直到隐藏到该界面的下一层界面
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tuple"></param>
        public void HideWindowByOrder<T>(ITuple tuple = null) where T : AbsWindow
        {
            Type type = typeof(T);
            if (cacheWindows.TryGetValue(type, out var window))
            {
                //要隐藏的Window要有下一级Window在显示
                if (windows.Contains(window))
                {
                    int index = windows.IndexOf(window);
                    //可以关闭
                    if (index > 0)
                    {
                        for (int i = windows.Count - 1; i >= 0; i--)
                        {
                            AbsWindow curWindow = windows[i];
                            curWindow.OnHide(tuple);
                            RemoveCacheWindow(curWindow);
                            if (curWindow == window)
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }

        //关闭顶层Window
        public void Back()
        {
            //至少有一个window处于显示
            if (windows.Count > 1)
            {
                AbsWindow window = windows[windows.Count - 1];
                window.OnHide();
                windows.Remove(window);
                RemoveCacheWindow(window);
            }
        }

        private void RemoveCacheWindow(AbsWindow window)
        {
            Type type = window.GetType();
            if (cacheWindows.ContainsKey(type))
            {
                window.OnDestroy();
                cacheWindows.Remove(type);
            }
        }

        //显示常驻Window
        public void ShowResidentWindow<T>(ITuple tuple = null, Action action = null) where T : AbsWindow
        {
            try
            {
                Type type = typeof(T);
                if (!cacheWindows.TryGetValue(type, out var window))
                {
                    window = Activator.CreateInstance(type, UIMgr) as T;
                    cacheWindows.Add(type, window);
                    window.OnInit();
                }
                if (!residentWindows.Contains(window))
                {
                    residentWindows.Add(window);
                    window.OnShow(tuple, action);
                }
            }
            catch (System.Exception e)
            {
                UnityEngine.Debug.LogError(e.ToString());
            }
        }

        //隐藏常驻Window
        public void HideResidentWindow<T>(ITuple tuple = null) where T : AbsWindow
        {
            Type type = typeof(T);
            if (cacheWindows.TryGetValue(type, out var window))
            {
                if (residentWindows.Contains(window))
                {
                    window.OnHide(tuple);
                    residentWindows.Remove(window);
                    RemoveCacheWindow(window);
                }
            }
        }

    }
}